﻿using System;
using System.Reflection;

namespace OperationPlugins.Models
{
    public struct PropertyValue : ICloneable
    {
        private readonly Type _declaringType;
        private readonly string _propertyName;
        private readonly PropertyInfo _property;
        private readonly Type _propertyType;
        private readonly object _value;

        /// <summary>
        /// Gets the type that declares the property.
        /// </summary>
        public Type DeclaringType { get { return _declaringType; } }

        /// <summary>
        /// Gets the property name.
        /// </summary>
        public string PropertyName { get { return _propertyName; } }

        /// <summary>
        /// Gets the property.
        /// </summary>
        public PropertyInfo Property { get { return _property; } }

        /// <summary>
        /// Gets the property type.
        /// </summary>
        public Type PropertyType { get { return _propertyType; } }

        /// <summary>
        /// Gets the property value.
        /// </summary>
        public object Value { get { return _value; } }

        /// <summary>
        /// Initializes a new instance of the PropertyValue struct.
        /// </summary>
        /// <param name="declaringType">The type that declares the property..</param>
        /// <param name="propertyName">The property name.</param>
        /// <param name="property">The property.</param>
        /// <param name="propertyType">The property type.</param>
        /// <param name="value">The property value.</param>
        internal PropertyValue(Type declaringType, string propertyName, PropertyInfo property, Type propertyType, object value)
        {
            _declaringType = declaringType;
            _propertyName = propertyName;
            _property = property;
            _propertyType = propertyType;
            _value = value;
        }

        /// <summary>
        /// Creates a new instance (object) that is a copy of the current object. 
        /// </summary>
        /// <returns>A new object that is a copy of the current object.</returns>
        public object Clone()
        {
            return new PropertyValue(DeclaringType, 
                                     PropertyName, 
                                     Property, 
                                     PropertyType, 
                                     ObjectFactory.Clone(Value));
        }

    }
}
